<template>
  <div class="s-table">
    <!-- 通过绝对定位的方式修正 ElementUI 自身 flex 布局情况下尺寸计算错误问题 -->
    <div style="position: absolute; height: 100%; width: 100%">
      <div class="action-bar" v-if="actionBar">
        <a-icon type="printer" @click="printerTable($event)" />
        <a-icon type="export" @click="exportTable()" />
      </div>
      <el-table
        @row-click="rowClickHandler"
        @row-dblclick="rowDoubleClickHandler"
        @row-contextmenu="rowContextMenuHandler"
        @selection-change="selectionChangeHandler"
        :border="border"
        v-if="tableVisible"
        highlight-current-row
        :data="data"
        :cell-class-name="cellClass"
        :header-cell-class-name="headerCellClass"
        :span-method="arraySpanMethod"
        :height="actionBar ? 'calc(100% - 30px)' : '100%'"
        row-class-name="table-row"
        ref="table"
        :row-key="rowKey"
        :expand-row-keys="expandRowKeys"
      >
        <s-table-column
          v-for="option in tableColumns"
          :key="option.key"
          :option="option"
        >
          <template v-for="name in slotNames" :slot="name" slot-scope="item">
            <slot :name="name" v-bind="item"></slot>
          </template>
        </s-table-column>
      </el-table>
    </div>
    <!-- 用于监测元素尺寸变化 -->
    <iframe
      ref="iframe"
      style="
        position: absolute;
        visibility: hidden;
        border: none;
        width: 100%;
        height: 100%;
        z-index: -1;
      "
    ></iframe>
  </div>
</template>

<script>
/**
 * 本组件基于 ElementUI Table 组件开发
 */
import ElTable from "element-ui/lib/table";
import ExportJsonExcel from "js-export-excel";
import printJS from "print-js";
import api from "@/util/api";
import STableColumn from "@/components/STableColumn";

export default {
  name: "STable",
  components: { STableColumn, ElTable },
  props: {
    columns: {
      required: true,
      type: Array
    },
    actionBar: {
      type: Boolean,
      default: false
    },
    // window.open 导出
    excelOpen: {
      type: String,
      default: ''
    },
    //导出excel数据
    excelData: {
      type: Object,
      required: false
    },
    // page: true,
    // name: "降雨数据",
    // url: "",
    // params: null
    border: {
      type: Boolean,
      default: false
    },
    data: {
      required: true,
      type: Array
    },
    inlineEdit: {
      type: Boolean,
      required: false,
      default: false
    },
    rowKey: {
      type: String
    },
    expandRowKeys: {
      type: Array
    },
    arraySpanMethod: {
      type: Function,
      default: null
    },
    cellClass: {
      type: Function,
      default: null
    },
    headerCellClass: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
      tableVisible: true
    };
  },
  mounted() {},
  computed: {
    tableColumns() {
      const fn = item => {
        const col = {
          ...item
        };

        if (col.children) {
          col.children = col.children.map(fn);
        } else {
          if (!(col.minWidth || col.width)) {
            col.minWidth = 160;
          }
        }

        if (col.type === "number") {
          col.align = col.align || "right";
        }

        if (col.type === "actions") {
          col.slot = "actions";
        }

        if (col.scrollFixed) {
          col.align = "center";
        }

        return col;
      };

      if (this.tabs) {
        return this.currentTab.columns.map(fn);
      }
      return this.columns.map(fn);
    },
    slotNames() {
      return Object.keys(this.$scopedSlots);
    }
  },
  watch: {
    columns: {
      handler() {
        this.tableVisible = false;
        this.$nextTick(() => {
          this.tableVisible = true;
          this.$nextTick(() => {
            setTimeout(() => {
              this.setResizeListener();
            }, 100);
          });
        });
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    selectedByDefault(row) {
      this.$nextTick(() => {
        this.$refs.table.setCurrentRow(row);
      });
    },
    printerTable() {
      const properties = [];
      let printable = [];
      this.columns.forEach(item => {
        if (item.title === "操作" || item.type === "index") {
          return;
        }
        properties.push({
          field: item.dataIndex,
          displayName: item.title
        });
      });
      if (this.columns[0].type === "index") {
        properties.unshift({
          field: "index",
          displayName: "序号"
        });
        printable = this.data.map((item, index) => {
          return {
            ...item,
            index: index + 1
          };
        });
      } else {
        printable = this.data;
      }
      printable.forEach(item => {
        for (const itemJson in item) {
          item[itemJson] = item[itemJson] ?? "--";
        }
      });
      printJS({
        printable: printable,
        properties: properties,
        type: "json",
        onError: () => {
          console.log(1111);
        }
      });
    },
    exportTable() {
      if(this.excelOpen){
        // 后端导出
        api.get('/api/cbb-szh-pptn/exp/auth/download-key').then(res => {
          window.open(this.excelOpen + `&downloadKey=${res}`)
        })
      }else {
        if (this.excelData && this.excelData["page"]) {
          api.get(this.excelData.url, {params: this.excelData.params}).then(res=>{
            this.exportStart((res && res['records']) || [])
          })
        }else {
          this.exportStart(this.data)
        }
      }

    },
    exportStart(data) {
      const properties = [];
      const sheetFilter = [];
      const columnWidths = [];
      this.columns.forEach(item => {
        if (item.title === "操作" || item.type === "index") {
          return;
        }
        properties.push(item.title);
        sheetFilter.push(item.dataIndex);
        columnWidths.push((item.minWidth || item.width) / 20);
      });
      const option = {
        fileName: this.excelData["name"],
        datas: [
          {
            sheetData: data,
            sheetName: "Excel 工作表",
            sheetHeader: properties,
            sheetFilter: sheetFilter,
            columnWidths: columnWidths
          }
        ]
      };
      const toExcel = new ExportJsonExcel(option);
      toExcel.saveExcel();
    },
    setResizeListener() {
      if (!this.$refs.table) {
        return;
      }
      this.$refs.table.doLayout();

      this.$refs.table.$el
        .querySelector(".el-table__body-wrapper")
        .removeEventListener("scroll", this.onResize);
      this.$refs.iframe.contentWindow.removeEventListener(
        "resize",
        this.onResize
      );

      this.$refs.table.$el
        .querySelector(".el-table__body-wrapper")
        .addEventListener("scroll", this.onResize, { passive: true });
      this.$refs.iframe.contentWindow.addEventListener(
        "resize",
        this.onResize,
        { passive: true }
      );

      this.onResize();
    },
    onResize() {
      const table = this.$refs.table.$el;
      const leftEl = this.$refs.table.$el.querySelector(".el-table__fixed");
      const rightEl = this.$refs.table.$el.querySelector(
        ".el-table__fixed-right"
      );

      const leftBox = leftEl
        ? leftEl.getBoundingClientRect()
        : {
            width: 0,
            height: 0,
            left: table.getBoundingClientRect().left,
            right: table.getBoundingClientRect().left
          };
      const rightBox = rightEl
        ? rightEl.getBoundingClientRect()
        : {
            width: 0,
            height: 0,
            left: table.getBoundingClientRect().right,
            right: table.getBoundingClientRect().right
          };

      Array.from(
        this.$refs.table.$el.querySelectorAll("th.scroll-fixed")
      ).forEach(header => {
        const headerBox = header.getBoundingClientRect();

        const left =
          headerBox.left < leftBox.right ? leftBox.right : headerBox.left;
        const right =
          headerBox.left + headerBox.width < rightBox.left
            ? headerBox.left + headerBox.width
            : rightBox.left;

        const cell = header.querySelector(".cell.scroll-fixed");
        const cellBox = cell.getBoundingClientRect();

        cell.style.position = "absolute";

        if (right - left <= 0) {
          // cell.style.position = "static";
        } else if (right - left > cellBox.width) {
          cell.style.left = (left + right) / 2 - headerBox.left + "px";
        } else if (headerBox.left < left) {
          cell.style.left = right - cellBox.width / 2 - headerBox.left + "px";
        } else {
          cell.style.left = left + cellBox.width / 2 - headerBox.left + "px";
        }
      });
    },
    rowClickHandler(...args) {
      this.$emit("row-click", ...args);
    },
    rowDoubleClickHandler(...args) {
      this.$emit("row-dblclick", ...args);
    },
    rowContextMenuHandler(...args) {
      this.$emit("row-contextmenu", ...args);
    },
    selectionChangeHandler(selection) {
      this.$emit("selection-change", selection);
    },
    clearSelection() {
      this.$refs.table.clearSelection();
      this.selectionChangeHandler([]);
    }
  }
};
</script>

<style lang="scss">
@import "~element-ui/lib/theme-chalk/table.css";
@import "~element-ui/lib/theme-chalk/table-column.css";

.action-bar {
  height: 30px;
  border: 1px solid #ebeef5;
  border-bottom: 0;
  background: #fafafa;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  i {
    margin-right: 10px;
    font-size: 20px;
    cursor: pointer;
  }
}
.s-table {
  position: relative;
  height: 100%;

  color: #434343;
  .is-center.scroll-fixed {
    text-align: left;
  }

  .cell.scroll-fixed {
    display: inline-block;
    width: auto;
    transition: margin-left 10ms;
    position: fixed;
    transform: translateY(-10px) translateX(-50%);
  }
  .el-table thead.is-group th,
  .el-table thead th {
    background-color: #fafafa;
  }

  .el-table td,
  .el-table th {
    padding: 11px 0;
    border-color: #f0f0f0;
    line-height: 22px;
  }

  .el-table--border,
  .el-table--group {
    border-color: #f0f0f0;
  }

  .el-table .cell,
  .el-table th > .cell {
    padding: 0 8px;
    height: 23px;
    white-space: nowrap;
    color: #434343;
  }

  .el-table .cell {
    font-weight: 400;
  }

  .el-table th > .cell {
    font-weight: 700;
  }

  .el-table .ant-btn-link {
    height: auto;
    line-height: 1;
  }

  .el-table__body tr:hover > td,
  .el-table__body tr.hover-row.current-row > td,
  .el-table__body tr.hover-row.el-table__row--striped.current-row > td,
  .el-table__body tr.hover-row.el-table__row--striped > td,
  .el-table__body tr.hover-row > td {
    background-color: #f5f5f5 !important;
  }

  .el-table {
    color: #434343;
  }

  .number {
    font-family: Roboto Mono;
  }

  /* .table-row { */
  /* cursor: pointer; */
  /* } */
}
</style>
